package com.xncoding.netty.socket.my.nio.demo01;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;

public class NioServerHander extends Thread {
        private Selector selector;
        private Charset charset;
        public NioServerHander(Selector selector, Charset charset) {
            this.selector = selector;
            this.charset = charset;
        }
        @Override
        public void run() {
            while (true) {
                try {
                    selector.select(1000);
                    Set<SelectionKey> selectedKeys = selector.selectedKeys();
                    Iterator<SelectionKey> it = selectedKeys.iterator();
                    SelectionKey key = null;
                    while (it.hasNext()) {
                        key = it.next();
                        it.remove();
                        if (!key.isValid()){
                            continue;
                        }
                        dispatch(key);
                    }
                } catch (Exception ignore) {
                }
            }
        }
        private void dispatch(SelectionKey key) throws IOException {
            if (key.isAcceptable()) {
                register(key);
            }else if (key.isReadable()) {
                read(key);
            }
        }

        private void register(SelectionKey key) throws IOException {
            ServerSocketChannel serverSocketChannelKey = (ServerSocketChannel) key.channel();
            SocketChannel socketChannel = serverSocketChannelKey.accept();
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);
        }

        private void read(SelectionKey key) throws IOException {
            SocketChannel socketChannelKey = (SocketChannel) key.channel();
            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            int readBytes = socketChannelKey.read(readBuffer);
            if (readBytes > 0) {
                readBuffer.flip();
                byte[] bytes = new byte[readBuffer.remaining()];
                readBuffer.get(bytes);
                String body = new String(bytes, "utf-8");
                System.out.println("服务端收到消息是：" + body);
                String currentTime = "服务端回复：".equalsIgnoreCase(body) ? new Date().toString() : "Bad Order";
                //回复客户端请求
                doWrite(socketChannelKey,currentTime);
            } else if (readBytes < 0) {
                key.cancel();
                socketChannelKey.close();
            } else {
                //读到0字节，忽略
            }
        }

        private void doWrite(SocketChannel socketChannel, String data) throws IOException {
            if (data != null && data.trim().length() > 0) {
                byte[] bytes = data.getBytes();
                ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
                byteBuffer.put(bytes);
                byteBuffer.flip();
                socketChannel.write(byteBuffer);
            }
        }

}
